package com.otupia.blog.dao;

import java.io.File;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;

import org.apache.log4j.Logger;

import javax.sql.DataSource;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.ResultSetExtractor;

import com.otupia.blog.context.BeanPoolSpringImpl;
import com.otupia.blog.model.Blog;

public class BlogDaoImpl implements BlogDao
{
	// private final String

	private static ResourceBundle SQLResourceBundle;

	private static Logger logger = Logger.getLogger(BlogDao.class);

	private DataSource dataSource;
	
	private JdbcTemplate jdbcTmpl;

	public void setDataSource(DataSource dataSource)
	{
		logger.info("calling function BlogDaoImpl"
				+ "#setDataSource with arguments : [" + dataSource + "]");
		this.dataSource = dataSource;
		this.jdbcTmpl = new JdbcTemplate(dataSource);

		logger.info("exiting function BlogDaoImpl"
				+ "#setDataSource with result : [" + "void" + "]");
	}

	public void setSQLResourceBundle(String resourceBundle_path)
	{
		SQLResourceBundle = ResourceBundle.getBundle(resourceBundle_path,
				Locale.getDefault());
		System.out.println("SQLResourceBundle  " + SQLResourceBundle);
		
		logger.info("exiting function BlogDaoImpl"
				+ "#setDataSource with result : [" + "void" + "]");
	}

	private Blog getBlogFromRs(ResultSet rs) throws SQLException
	{
		logger.info("calling function BlogDaoImpl"
				+ "#getBlogFromRs with arguments : [" + rs + "]");
		Blog blog = new Blog();
		blog.setTitle(rs.getString("title"));
		blog.setContent(rs.getString("content"));
		blog.setId(rs.getLong("id"));

		logger.info("exiting function BlogDaoImpl"
				+ "#getBlogFromRs with result : [" + blog + "]");
		return blog;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Blog> findBlogByWriter(final long writerId)
	{

		logger.info("calling function BlogDaoImpl"
				+ "#findBlogByWriter with arguments : [" + writerId + "]");

		JdbcTemplate jdbcTmpl = new JdbcTemplate(dataSource);

		PreparedStatementCreator psc = new PreparedStatementCreator()
		{

			@Override
			public PreparedStatement createPreparedStatement(Connection con)
					throws SQLException
			{
				logger.info("query sql is : "
						+ BlogDaoImpl.SQLResourceBundle
								.getString("blog.queryByWriterId"));
				return con.prepareStatement(BlogDaoImpl.SQLResourceBundle
						.getString("blog.queryByWriterId"));
			}

		};

		PreparedStatementSetter pss = new PreparedStatementSetter()
		{

			@Override
			public void setValues(PreparedStatement ps) throws SQLException
			{
				ps.setLong(1, writerId);
			}

		};

		ResultSetExtractor rse = new ResultSetExtractor()
		{

			@Override
			public Object extractData(ResultSet rs) throws SQLException,
					DataAccessException
			{
				List result = new ArrayList();

				Blog blog = null;
				while (rs.next())
				{
					blog = getBlogFromRs(rs);
					result.add(blog);
				}
				return result;
			}

		};

		List<Blog> query = (List<Blog>) jdbcTmpl.query(psc, pss, rse);

		logger.info("exiting function BlogDaoImpl"
				+ "#findBlogByWriter with result : [" + query + "]");
		return query;
	}

	@Override
	public Blog findBlogById(final long id)
	{
		logger.info("calling function BlogDaoImpl"
				+ "#findBlogById with arguments : [" + id + "]");

		PreparedStatementCreator psc = new PreparedStatementCreator()
		{

			@Override
			public PreparedStatement createPreparedStatement(Connection con)
					throws SQLException
			{
				logger.info("query sql is : "
						+ BlogDaoImpl.SQLResourceBundle
								.getString("blog.queryByBlogId"));

				return con.prepareStatement(BlogDaoImpl.SQLResourceBundle
						.getString("blog.queryByBlogId"));
			}

		};

		PreparedStatementSetter pss = new PreparedStatementSetter()
		{

			@Override
			public void setValues(PreparedStatement ps) throws SQLException
			{
				ps.setLong(1, id);
			}

		};

		ResultSetExtractor rse = new ResultSetExtractor()
		{

			@Override
			public Object extractData(ResultSet rs) throws SQLException,
					DataAccessException
			{
				Blog blog = null;
				if (rs.next())
				{
					blog = getBlogFromRs(rs);
				}
				return blog;
			}

		};

		logger.info("exiting function BlogDaoImpl"
				+ "#findBlogById with result : ["
				+ jdbcTmpl.query(psc, pss, rse) + "]");
		return (Blog) jdbcTmpl.query(psc, pss, rse);
	}

	@Override
	public void insertBlog(Blog blog)
	{
		logger.info("calling function BlogDaoImpl"
				+ "#insertBlog with arguments : [" + blog + "]");
		String insertSql = BlogDaoImpl.SQLResourceBundle
				.getString("blog.insertBlog");
		Object[] params = new Object[]
		{ blog.getTitle(), blog.getContent(), blog.getWriter_id() };
		this.jdbcTmpl.update(insertSql, params);

		logger.info("exiting function BlogDaoImpl"
				+ "#insertBlog with result : [" + "void" + "]");
	}

	@Override
	public void deleteBlogById(long id)
	{
		logger.info("calling function BlogDaoImpl"
				+ "#deleteBlogById with arguments : [" + id + "]");

		String deleteSQL = BlogDaoImpl.SQLResourceBundle
				.getString("blog.deleteBlog");
		Object[] params = new Object[]
		{ id };
		this.jdbcTmpl.update(deleteSQL, params);

		logger.info("exiting function BlogDaoImpl"
				+ "#deleteBlogById with result : [" + "void" + "]");

	}

	@Override
	public void updateBlog(Blog blog)
	{
		logger.info("calling function BlogDaoImpl"
				+ "#updateBlog with arguments : [" + blog + "]");

		String updateSQL = BlogDaoImpl.SQLResourceBundle
				.getString("blog.updateBlog");

		Object[] params = new Object[]
		{ blog.getTitle(), blog.getContent(), blog.getId() };

		this.jdbcTmpl.update(updateSQL, params);

		logger.info("exiting function BlogDaoImpl"
				+ "#updateBlog with result : [" + "void" + "]");
	}

	@Override
	public List<Blog> findBlogByTitle(final String title)
	{
		logger.info("calling function BlogDaoImpl"
				+ "#findBlogByTitle with arguments : [" + title + "]");

		JdbcTemplate jdbcTmpl = new JdbcTemplate(dataSource);

		PreparedStatementCreator psc = new PreparedStatementCreator()
		{

			@Override
			public PreparedStatement createPreparedStatement(Connection con)
					throws SQLException
			{
				logger.info("query sql is : "
						+ BlogDaoImpl.SQLResourceBundle
								.getString("blog.queryByTitle"));
				return con.prepareStatement(BlogDaoImpl.SQLResourceBundle
						.getString("blog.queryByTitle"));
			}

		};

		PreparedStatementSetter pss = new PreparedStatementSetter()
		{

			@Override
			public void setValues(PreparedStatement ps) throws SQLException
			{
				ps.setString(1, title + "%");
			}

		};

		ResultSetExtractor rse = new ResultSetExtractor()
		{

			@Override
			public Object extractData(ResultSet rs) throws SQLException,
					DataAccessException
			{
				List result = new ArrayList();

				Blog blog = null;
				while (rs.next())
				{
					blog = getBlogFromRs(rs);
					result.add(blog);
				}
				return result;
			}

		};

		List<Blog> query = (List<Blog>) jdbcTmpl.query(psc, pss, rse);

		logger.info("exiting function BlogDaoImpl"
				+ "#findBlogByTitle with result : [" + query + "]");
		return query;
	}
}
